﻿#region License
// Copyright (c) 2009 Shengmin Zhang
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
#endregion
using System;
using System.Collections.Generic;
using System.Text;
using System.Web;
using System.Collections.Specialized;
using System.Security.Permissions;

using Apprender.Utilities;
using Apprender.Web.Configuration;
using Apprender.Web.UI;

namespace Apprender.Web
{
    [AspNetHostingPermission(SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
    [AspNetHostingPermission(SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]    
    public sealed class ClientResourceManager
    {
        #region Fields

        private ClientResourceSection _section;
        private ClientResourceGroupCollection _jsGroupListInConfig;
        private ClientResourceGroupCollection _cssGroupListInConfig;

        private HtmlBuilder _html = new HtmlBuilder();

        private int _jsGroupCountInConfig;
        private int _cssGroupCountInConfig;

        private List<ClientResourceGroup> _jsGroupList;
        public List<ClientResourceGroup> JavaScriptGroup
        {
            get { return this._jsGroupList; }
        }

        private List<ClientResourceGroup> _cssGroupList;
        public List<ClientResourceGroup> CssGroup
        {
            get { return this._cssGroupList; }
        }

        private int _jsGroupCount;
        private int _cssGroupCount;

        #endregion

        public ClientResourceManager(List<ClientResourceGroup> jsGroupList, List<ClientResourceGroup> cssGroupList)
        {
            this._cssGroupList = cssGroupList;
            this._jsGroupList = jsGroupList;
        }

        public ClientResourceManager()
        {
            this._jsGroupList = new List<ClientResourceGroup>(1);
            this._cssGroupList = new List<ClientResourceGroup>(1);
        }

        public string GetHtml()
        {
            SetVariables();

            StringBuilder sb = new StringBuilder(100 * (this._jsGroupCountInConfig + this._cssGroupCountInConfig + this._jsGroupCount + this._cssGroupCount));

            this.PopulateWithJavaScript(sb);

            //add page script if exists
            string js = HttpContext.Current.Request.QueryString["js"];
            if (js != null)
            {
                _html.Script(@"res.axd?t=js&p=~/" + js, sb);
            }

            this.PopulateWithCss(sb);

            return sb.ToString();
        }        

        private void SetVariables()
        {
            this._section = ApprenderWebSectionGroup.ClientResource;//ClientResourceSection.Configuration;
            this._jsGroupListInConfig = this._section.JavaScript;
            this._cssGroupListInConfig = this._section.Css;

            this._jsGroupCountInConfig = this._jsGroupListInConfig.Count;
            this._cssGroupCountInConfig = this._cssGroupListInConfig.Count;

            this._jsGroupCount = this._jsGroupList.Count;
            this._cssGroupCount = this._cssGroupList.Count;
        }

        private void PopulateWithJavaScript(IList<IClientResource> resx, StringBuilder sb)
        {
            for (int i = 0; i < resx.Count; i++)
            {
                _html.Script(UPath.ResolvePath(resx[i].Path), sb);
            }
        }

        private void PopulateWithCss(IList<IClientResource> resx, StringBuilder sb)
        {
            for (int i = 0; i < resx.Count; i++)
            {                
                _html.Link(UPath.ResolvePath(resx[i].Path), sb);
            }
        }

        private void PopulateWithJavaScript(StringBuilder sb)
        {            
            for (int i = 0; i < this._jsGroupCountInConfig; i++)
            {
                var resx = this._jsGroupListInConfig[i];
#if DEBUG
                this.PopulateWithJavaScript(resx, sb);
#else
                if (resx.EnableProcessing)
                {
                    this._html.Script(resx, sb);
                }
                else
                {
                    this.PopulateWithJavaScript(resx, sb);
                }
#endif
            }
            
            for (int i = 0; i < this._jsGroupCount; i++)
            {
                var resx = this._jsGroupList[i];
#if DEBUG
                this.PopulateWithJavaScript(resx, sb);
#else
                if (resx.EnableProcessing)
                {
                    this._html.Script(resx, sb);
                }
                else
                {
                    this.PopulateWithJavaScript(resx, sb);
                }
#endif
            }
            
        }

        private void PopulateWithCss(StringBuilder sb)
        {
            for (int i = 0; i < this._cssGroupCountInConfig; i++)
            {
                var resx = this._cssGroupListInConfig[i];
#if DEBUG
                this.PopulateWithCss(resx, sb);
#else
                if (resx.EnableProcessing)
                {
                    this._html.Link(resx, sb);
                }
                else
                {
                    this.PopulateWithCss(resx, sb);
                }
#endif
            }
           
            for (int i = 0; i < this._cssGroupCount; i++)
            {
                var resx = this._cssGroupList[i];
#if DEBUG
                this.PopulateWithCss(resx, sb);
#else

                if (resx.EnableProcessing)
                {
                    this._html.Link(resx, sb);
                }
                else
                {
                    this.PopulateWithCss(resx, sb);
                }
#endif
            }            
        }
    }
}
